#include "lm_listview.h"
#include "lm_keyevent.h"
#include "../common/lm_mem.h"

static bool lm_listview_node_is_first(lm_list_node_t *head, lm_list_node_t *node)
{
    return lm_list_next_node(head) == node;
}

static bool lm_listview_node_is_last(lm_list_node_t *head, lm_list_node_t *node)
{
    return lm_list_prev_node(head) == node;
}

static int lm_listview_keyboard_handler(lm_title_win_t *win, lm_list_node_t *head, lm_color_t color)
{
    int kb_input;
    int pos_y = 0;
    int select = 0;

    lm_list_node_t *node = lm_list_next_node(head);
    lm_listview_node_t *listview_node;

    while(1) {
        kb_input = lm_get_kb_value();

        if(kb_input != KEYBOARD_INVALID)
        {
            if(kb_input == KEYBOARD_ENTER) {
                return select;
            }
            else if(kb_input == KEYBOARD_UP) {

                if(!lm_listview_node_is_first(head, node)) {
                    
                    listview_node = container_of(node, lm_listview_node_t, link);
                    lm_title_win_set_pos_text(win, 4, pos_y, listview_node->text, color.pair);

                    if(pos_y == 0) {
                        lm_title_win_scrol_down(win);
                    }
                    else {
                        pos_y --;
                    }

                    select -- ;

                    node = lm_list_prev_node(node);
                    listview_node = container_of(node, lm_listview_node_t, link);
                    lm_title_win_set_pos_text(win, 4, pos_y, listview_node->text, lm_color_swap(color));

                    lm_title_win_refresh(win);
                }
            }
            else if(kb_input == KEYBOARD_DOWN) {

                if(! lm_listview_node_is_last(head, node) ) {

                    listview_node = container_of(node, lm_listview_node_t, link);
                    lm_title_win_set_pos_text(win, 4, pos_y, listview_node->text, color.pair);

                    if(pos_y == (getmaxy(win->window.body) - 1)) {
                        lm_title_win_scrol_up(win);
                    }
                    else {
                        pos_y ++;
                    }

                    select ++ ;

                    node = lm_list_next_node(node);
                    listview_node = container_of(node, lm_listview_node_t, link);
                    lm_title_win_set_pos_text(win, 4, pos_y, listview_node->text, lm_color_swap(color));

                    lm_title_win_refresh(win);
                    
                }
            }            
        }
    }

    return select;
}


char* lm_listview_create(int x, int y, int32_t width, int32_t height, const char* title, lm_list_node_t* head, lm_color_t color)
{
    lm_listview_t *listview = lm_malloc(sizeof(lm_listview_t));
    if(listview == NULL) {
        return NULL;
    }

    lm_title_win_t* win = &listview->win;
    win = lm_title_win_create(NULL, x, y, width, height, title, color);
    if(win == NULL) {
        return NULL;
    }

    lm_list_init(&listview->head);
    listview->current = 0;
    
    listview->color = color;
    listview->color.pair = lm_win_set_color(win->window.body, color);
    color.pair = listview->color.pair;

    lm_listview_node_t *listview_node; 
    lm_list_node_t *node;
    int pos_y = 0;

    lm_list_for_each(node, head) {

        listview_node = container_of(node, lm_listview_node_t, link);

        if(pos_y <= getmaxy(win->window.body)) {
            if(listview->current == pos_y) {
                wattrset(win->window.body, COLOR_PAIR(lm_color_swap(color)));
            }
            else {
                wattrset(win->window.body, COLOR_PAIR(listview->color.pair));
            }
            mvwaddstr(win->window.body, pos_y, 4, listview_node->text);
        }
        else {
            break;
        }
        pos_y ++;
    }
    lm_title_win_refresh(win);

    listview->current = lm_listview_keyboard_handler(win, head, color);

    node = head;
    for(int i = 0; i <= listview->current; i++) {
        node = lm_list_next_node(node);
    }
    listview_node = container_of(node, lm_listview_node_t, link);

    lm_title_win_delete(win);

    return listview_node->text;
}

int lm_listview_add_item(lm_list_node_t* head, char* text)
{
    lm_listview_node_t *node = lm_malloc(sizeof(lm_listview_node_t));
    if(node == NULL) {
        return -1;
    }

    node->text = text;
    
    lm_list_add_node_at_tail(head, &node->link);

    return 0;
}

